package note_002;

public class day08 {
    /**
     * 当前一个线程调用Thread.sleep()方法处于睡眠阻塞的过程中，若该线程的interrupt()方法被调用时，会
     * 中断该线程的睡眠阻塞，此时该线程会抛出中断异常.
     */
    /** interrupt() 中断该线程的睡眠阻塞,该线程会抛出中断异常 */
    //中断该线程的睡眠阻塞,该线程会抛出中断异常
    /**
     * 守护线程:
     * 守护线程又称为后台线程，守护线程是通过普通的线程调用setDaemon(true)设置而转变来的。因此线程
     * 定义和创建与普通线程一致。
     *
     * 守护线程在结束时机上有一点于普通线程不同:  进程的结束。
     *
     * 进程的结束:
     * 当一个Java进程中的所有普通线程都结束时，该线程就会结束，此时会强制刺杀所有正在运行的守护线程。
     *
     */
    /** setDaemon(true):普通的线程调用,设置守护进程 */
    //setDaemon(true)必须在线程start()启动之前调用，否则抛出异常.
    //会强制刺杀所有正在运行的守护线程

    /**
     * 线程提供了一个方法:
     * void join()
     * 该方法允许一个线程在另一个线程上等待，直到其执行完毕后才会继续后续的工作。
     * 所有join方法可以协调线程之间的同步运行。
     * <p>
     * 同步运行:多个线程执行存在先后顺序。
     * 异步运行:多个线程执行时各干各的。
     * ------线程之间本来就是异步运行的.
     */
    /** .join():等待 */
    /* 等待download下载完毕(阻塞show线程等待download执行完毕) */
    //download.join();//等待线程死亡,结束
//    if(!isFinish){

    /**
     * 抛出新的运行时异常
     */
//        throw new RuntimeException("show:图片加载失败~");//当向外抛出时,该线程会被直接杀掉,但不影响其他线程.
//    }
    public static void main(String[] args) {
        /**
         当一个方法的局部变量被该方法的其他内部类引用时，这个局部变量必须是final的。
         JDK8之后可以不显示的用final关键词修饰该变量，但是该特点依然存在.
         */
//        boolean isFinish = false;//从内部类访问变量“isFinish”，需要是最终的或有效的最终
    }

    /**
     * 多线程并发的安全问题:------------------------------------------------------------
     * 当多个线程并发操作同一临界资源时，由于线程切换时机不确定，导致操作过程的顺序出现了混乱从而导致
     * 操作临界资源出现错误而产生一系列问题。
     * <p>
     * 临界资源:操作该资源的过程同时只能被单一线程进行的资源.
     */

    /**
     * synchronized有两种使用方式
     * 在方法上修饰,此时该方法变为一个同步方法
     * 同步块,可以更准确的锁定需要排队的代码片段
     *
     * synchronized 同步方法.
     * -------在方法上使用synchronized时，同步监视器对象就是当前方法所属对象，即:this
     * -------static方法:没有隐士this.
     *                  当静态方法使用synchronized修饰后，该方法一定具有同步效果.
     */

    //并发操作改为同步排队操作,
//    public synchronized int getBean() {}
     /*
        当一个方法使用关键词synchronized修饰后，这个方法称为同步方法，
        即:多个线程不能同时在方法内部执行，只能有先后顺序的一个一个执行该方法。
        将多线程并发操作改为同步排队操作可能有效解决多线程并发安全问题.
     */

//    public synchronized static void dosome() {
     /*
        在静态方法上使用synchronized后，该静态方法变为同步的，而同步监视器对象为当前类的类对象.
        即:Class的实例.
        注:JVM中每个被加载的类都有且只有一个Class的实例与之对应，静态方法锁的就只这个对象.
        而类对象会在后期的反射知识点中介绍.

        public static void dosome() {
        //同步块在静态方法中指定的锁对象通常也是当前类的类对象，获取方式:类名.class
        synchronized (当前类的类名.class) {}
     */
    /** yield() 向调度程序提示当前线程愿意放弃其当前对处理器的使用 */
    //它可能有助于重现由于竞争条件引起的错误。
    /*
    static void yield()
    线程提供的这个静态方法作用是让执行该方法的线程
    主动放弃本次时间片。
    这里使用它的目的是模拟执行到这里CPU没有时间了，发生
    线程切换，来看并发安全问题的产生。
     */

    /**
     * 同步块
     * 语法:
     * synchronized(同步监视器对象){
     *     需要同步执行的代码片段
     * }
     *
     * 使用同步块可以更精准的锁定需要多个线程同步执行的代码片段，有效的缩小排队范围可以在保证并发安全的
     * 前提下提高并发效率.
     *
     */
    /** synchronized (this) {} : 同步块 */
            /*
                使用同步块时要在()中指定同步监视器对象，该对象可以是Java中任何的实例，但是
                必须保证多个需要同步执行该代码块的线程看到的这个同步监视器对象是同一个才可以.
             */
//    synchronized (this) {//--------需要同步执行的代码片段
////            synchronized (new Object()) {//new Object : 没有解决多线程并发安全问题.
    /**
     * 互斥锁:
     * 使用多个synchronized锁定多个代码片段，而指定的同步监视器是同一个时，这些代码片段之间就是互斥的。
     * 即:多个线程不能同时执行这些代码片段.
     */
    /** 互斥锁: 指定的同步监视器(this)是同一个时,这些代码片段之间就是互斥的。*/
    /* 大白话:
      用同一个对象的方法，是相同的this，而方法synchronized修饰,
      则发生互斥现象.
      */
    /**
     * 死锁:
     * ---当两个线程各自持有一个锁的同时都在等待对方先释放锁时就会形成一种僵持状态，导致两个线程卡主。
     * 这种现象称为:---死锁现象.
     *
     * 避免一个线程在持有一个锁的过程中,再去持有另一个锁.
     * 原则上持有一个对象锁后将该操作做完就立刻释放,后再去持有其他的锁.
     */


}
